﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;


namespace Development.Tools
{
    [Serializable]
	public class CSV
	{
	    private readonly List<List<string>> m_CellList = new List<List<string>>();
	    private string m_Path;
	    private string m_FileName;
	
	    public const string DefalutCellValue = "0";
	
	    public CSV()
	    {
	    }
	
	    public CSV(string path, string fileName)
	    {
	        this.m_Path = path;
	        this.m_FileName = fileName;
	
	    }
	
	   
	    public bool Load()
	    {
	        Load(",");
	        return true;
	    }

	
	    private bool Load(string span)
	    {
	        //文件路径和文件名
	        string files = m_Path + "/" + m_FileName;
	        StreamReader fileReader = new StreamReader(files, Encoding.Default);
	
	        List<List<string>> CellList = new List<List<string>>();
	        try
	        {
	            int lsi = 0;
	            string cv = span;
	            while (fileReader.EndOfStream == false)
	            {
	                string line = fileReader.ReadLine();
	                string[] y = line.Split(Convert.ToChar(cv));
	                if (lsi > 0)
	                {
	                    CellList.Add(new List<string>());
	                    //第一列为注释
	                    //从第二列开始为Field字段
	                    //从第三列开始为数据段                                                
	                    for (int i = 0; i < y.Length; i++)
	                    {
	                        string cellValue = y[i].Trim().ToString();
	
	                        if (cellValue.Equals(""))
	                        {
	                            CellList[lsi - 1].Add(DefalutCellValue);
	                        }
	                        else
	                        {
	                            CellList[lsi - 1].Add(y[i].Trim().ToString());
	                        }
	                    }
	                }
	                lsi++;
	            }
	        }
	        catch (IOException ex)
	        {
	            throw ex;
	        }
	        finally
	        {
	            fileReader.Close();
	            fileReader.Dispose();
	        }
	
	        RemoveBlankRow(CellList);
	        //RemoveBlankCol(CellList);
	        RemoveBlankField();
	
	        CellList.Clear();
	        return true;
	    }
	
	    // 删除空行
	    private void RemoveBlankRow(List<List<string>> CellList)
	    {
	        for (int i = 0; i < CellList.Count; ++i)
	        {
	            if (CellList[i][0].Equals("0"))
	            {
	                CellList.RemoveAt(i);
	                i--;
	            }
	        }
	    }
	
	    // 删除空列
	    private void RemoveBlankCol(List<List<string>> CellList)
	    {
	        if (CellList.Count < 2)
	            return;
	
	        List<string> FieldList = CellList[0];
	        for (int i = 0; i < CellList.Count; ++i)
	        {
	            m_CellList.Add(new List<string>());
	            for (int j = 0; j < FieldList.Count; ++j)
	            {
	                if (!FieldList[j].Equals(DefalutCellValue))
	                {
						if(CellList[i].Count > j)
	                    	m_CellList[i].Add(CellList[i][j]);
						else
							m_CellList[i].Add(DefalutCellValue);
	                }
	            }
	        }
	    }
	
	    // 删除空的字段
	    private void RemoveBlankField()
	    {
	        List<string> FieldList = m_CellList[0];
	        for (int i = 0; i < FieldList.Count; ++i)
	        {
	            if (FieldList[i].Equals(DefalutCellValue))
	            {
	                FieldList.RemoveAt(i);
	                i--;
	            }
	        }
	    }
	
	    public bool IsLoaded()
	    {
	        return m_CellList.Count >= 2;
	    }
	
	    public int GetMaxRow()
	    {
	        return m_CellList.Count;
	    }
	
	    public int RowCount
	    {
	        get
	        {
	            return m_CellList.Count;
	        }
	    }
	
	    public int GetMaxCol()
	    {
	        return m_CellList[0].Count;
	    }
	
	    public int ColCount
	    {
	        get
	        {
	            return m_CellList[0].Count;
	        }
	    }
	
	    public List<string> GetRowsValue(int rowIndex)
	    {
	        return m_CellList[rowIndex];
	    }
	
	    public List<string> this[int rowIndex]
	    {
	        get
	        {
	            if (rowIndex > (RowCount - 1))
	                throw new IndexOutOfRangeException(string.Format("There is no record at index {0}.", rowIndex));
	
	            return m_CellList[rowIndex];
	        }
	    }
	
	    /// <summary>
	    /// 得到指定行、指定列的值
	    /// </summary>
	    /// <param name="rowIndex">row index</param>
	    /// <param name="colIndex">col index</param>
	    /// <returns></returns>
	    public string this[int rowIndex, int colIndex]
	    {
	        get
	        {
	            if (rowIndex > (RowCount - 1))
	                throw new IndexOutOfRangeException(string.Format("There is no row at index {0}.", rowIndex));
	
	            List<string> rowList = m_CellList[rowIndex];
	            if (colIndex > (rowList.Count - 1))
	                throw new IndexOutOfRangeException(string.Format("There is no col at index {0} in row {1}.", colIndex, rowIndex));
	
	            return rowList[colIndex];
	        }
	    }
	
	    /// <summary>
	    /// Gets the field value at the specified record index for the supplied field name
	    /// </summary>
	    /// <param name="rowIndex">row index</param>
	    /// <param name="colName">表头名字</param>
	    /// <returns></returns>
	    public string this[int rowIndex, string colName]
	    {
	        get
	        {
	            if (rowIndex > (RowCount - 1))
	                throw new IndexOutOfRangeException(string.Format("There is no row at index {0}.", rowIndex));
	
	            int colIndex = GetColNameIndex(colName);
	            if (colIndex < 0)
	            {
	                throw new ArgumentException(string.Format("There is no col header with the name '{0}'", colName));
	            }
	
	            return m_CellList[rowIndex][colIndex];
	        }
	    }
	
	    // 得到表头名字所在列
	    public int GetColNameIndex(string colName)
	    {
	        int colIndex = -1;
	
	        if (!IsLoaded())
	        {
	            throw new ArgumentException(string.Format("Csv: '{0}' row is less 2 row", m_FileName));
	        }
	
	        for (int i = 0; i < m_CellList[0].Count; i++)
	        {
	            if (string.Compare(m_CellList[0][i], colName) != 0)
	                continue;
	
	            colIndex = i;
	            break;
	        }
	
	        if (colIndex == -1)
	            throw new ArgumentException(string.Format("There is no col header with the name '{0}'", colName));
	
	        if (colIndex > (m_CellList[0].Count - 1))
	            throw new IndexOutOfRangeException(string.Format("There is no col at index {0}", colIndex));
	
	        return colIndex;
	    }
	
	
	    public List<string> GetColsValue(int colIndex)
	    {
	        if (colIndex >= GetMaxCol())
	        {
	            return null;
	        }
	
	        List<string> ColsList = new List<string>();
	
	        for (int i = 0; i < m_CellList.Count; ++i)
	        {
	            ColsList.Add(m_CellList[i][colIndex]);
	        }
	
	        return ColsList;
	    }
	
	    // 通过列名字得到 列数据    
	    public List<string> GetColsValue(string colName)
	    {
	        int colIndex = -1;
	        if (!m_CellList[0].Contains(colName))
	        {
	            throw new ArgumentException(string.Format("There is no col header with the name '{0}'", colName));
	        }
	
	        colIndex = GetColNameIndex(colName);
	        if (colIndex < 0)
	        {
	            throw new ArgumentException(string.Format("There is no col header with the name '{0}'", colName));
	        }
	
	        return GetColsValue(colIndex);
	    }
	
	
	    public bool QueryTableBool(int rowIndex, int colIndex)
	    {
	        return System.Convert.ToBoolean(m_CellList[rowIndex][colIndex]);
	    }
	
	    public bool QueryTableBool(int rowIndex, string colName)
	    {
	        int colIndex = -1;
	        colIndex = GetColNameIndex(colName);
	        if (colIndex < 0)
	        {
	            throw new ArgumentException(string.Format("There is no col header with the name '{0}'", colName));
	        }
	
	        return System.Convert.ToBoolean(m_CellList[rowIndex][colIndex]);
	    }
	
	    public int QueryTableInt(int Row, int Col)
	    {
	        return System.Convert.ToInt32(m_CellList[Row][Col]);
	    }
	
	    public int QueryTableInt(int rowIndex, string colName)
	    {
	        int colIndex = -1;
	        colIndex = GetColNameIndex(colName);
	        if (colIndex < 0)
	        {
	            throw new ArgumentException(string.Format("There is no col header with the name '{0}'", colName));
	        }
	        return System.Convert.ToInt32(m_CellList[rowIndex][colIndex]);
	    }
	
	    public string QueryTableString(int Row, int Col)
	    {
	        return (m_CellList[Row][Col]);
	    }
	
	    public string QueryTableString(int rowIndex, string colName)
	    {
	        int colIndex = -1;
	        colIndex = GetColNameIndex(colName);
	        if (colIndex < 0)
	        {
	            throw new ArgumentException(string.Format("There is no col header with the name '{0}'", colName));
	        }
	        return (m_CellList[rowIndex][colIndex]);
	    }
	
	    public float QueryTableFloat(int Row, int Col)
	    {
	        return (float)System.Convert.ToDouble(m_CellList[Row][Col]);
	    }
	
	    public float QueryTableFloat(int rowIndex, string colName)
	    {
	        int colIndex = -1;
	        colIndex = GetColNameIndex(colName);
	        if (colIndex < 0)
	        {
	            throw new ArgumentException(string.Format("There is no col header with the name '{0}'", colName));
	        }
	
	        return (float)System.Convert.ToDouble(m_CellList[rowIndex][colIndex]);
	    }
	
	    public double QueryTableDouble(int Row, int Col)
	    {
	        return System.Convert.ToDouble(m_CellList[Row][Col]);
	    }
	
	    public double QueryTableDouble(int rowIndex, string colName)
	    {
	        int colIndex = -1;
	        colIndex = GetColNameIndex(colName);
	        if (colIndex < 0)
	        {
	            throw new ArgumentException(string.Format("There is no col header with the name '{0}'", colName));
	        }
	
	        return System.Convert.ToDouble(m_CellList[rowIndex][colIndex]);
	    }
	
	    // 查找 第 Col列 中等于 value值得 行数
	    // 返回行数
	    public int FindTableIntRow(int Col, int value)
	    {
	        List<string> ColsList = GetColsValue(Col);
	        int retRow = -1;
	        for (int i = 0; i < ColsList.Count; i++)
	        {
	            if (ColsList[i].Equals(Convert.ToString(value)))
	            {
	                retRow = i;
	                break;
	            }
	        }
	        return retRow;
	    }
	
	    public int FindTableIntRow(string colName, int value)
	    {
	        List<string> ColsList = GetColsValue(colName);
	        int retRow = -1;
	        for (int i = 0; i < ColsList.Count; i++)
	        {
	            if (ColsList[i].Equals(Convert.ToString(value)))
	            {
	                retRow = i;
	                break;
	            }
	        }
	
	        return retRow;
	    }
	
	    public int FindTableStringRow(int Col, string value)
	    {
	        List<string> ColsList = GetColsValue(Col);
	        int retRow = -1;
	        for (int i = 0; i < ColsList.Count; i++)
	        {
	            if (ColsList[i].Equals(Convert.ToString(value)))
	            {
	                retRow = i;
	                break;
	            }
	        }
	        return retRow;
	    }
	
	    public int FindTableStringRow(string colName, string value)
	    {
	        List<string> ColsList = GetColsValue(colName);
	        int retRow = -1;
	        for (int i = 0; i < ColsList.Count; i++)
	        {
	            if (ColsList[i].Equals(Convert.ToString(value)))
	            {
	                retRow = i;
	                break;
	            }
	        }
	        return retRow;
	    }
	
	    public int FindTableFloatRow(int Col, float value)
	    {
	        List<string> ColsList = GetColsValue(Col);
	        int retRow = -1;
	        for (int i = 0; i < ColsList.Count; i++)
	        {
	            if (ColsList[i].Equals(Convert.ToString(value)))
	            {
	                retRow = i;
	                break;
	            }
	        }
	        return retRow;
	    }
	
	    public int FindTableFloatRow(string colName, float value)
	    {
	        List<string> ColsList = GetColsValue(colName);
	        int retRow = -1;
	        for (int i = 0; i < ColsList.Count; i++)
	        {
	            if (ColsList[i].Equals(Convert.ToString(value)))
	            {
	                retRow = i;
	                break;
	            }
	        }
	        return retRow;
	    }
	
	    public int FindTableDoubleRow(int Col, double value)
	    {
	        List<string> ColsList = GetColsValue(Col);
	        int retRow = -1;
	        for (int i = 0; i < ColsList.Count; i++)
	        {
	            if (ColsList[i].Equals(Convert.ToString(value)))
	            {
	                retRow = i;
	                break;
	            }
	        }
	        return retRow;
	    }
	
	    public int FindTableDoubleRow(string colName, double value)
	    {
	        List<string> ColsList = GetColsValue(colName);
	        int retRow = -1;
	        for (int i = 0; i < ColsList.Count; i++)
	        {
	            if (ColsList[i].Equals(Convert.ToString(value)))
	            {
	                retRow = i;
	                break;
	            }
	        }
	        return retRow;
	    }
		
		public static void SplitToContainer(string souceStr, List<int> container, char sep)
		{
			string[] arr = souceStr.Split(sep);
			for(int i = 0; i < arr.Length; ++i)
			{
				container.Add(System.Convert.ToInt32(arr[i]));
			}
		}
	}
	
}